package Meter::Test;

#===============================================================================
#     REVISION:  $Id: Test.pm 162 2011-09-18 17:02:10Z xdr.box@gmail.com $
#  DESCRIPTION:  Commonly used testing helper functions
#         NOTE:  To run WWW tests, add the following into your main apache.conf:
#                NameVirtualHost *:8080
#                Listen 8080
#                Include /path/to/meter-webapp/tests/apache/site-*.conf
#                Add the following into your envvars file:
#                export APACHE_LOG_DIR=/var/log/apache2
#===============================================================================

use strict;
use warnings;

use Readonly;
Readonly our $VERSION => qw($Revision: 162 $) [1];

use base qw(Exporter);
our @EXPORT_OK = qw(
    init_tmp_db
    init_apache
    get_test_webapp_url
    dump_compact
    get_action_link_regex
    u8
);

use English qw( -no_match_vars );
use File::Temp qw( tempfile );
use Carp;
use Data::Dumper;
use Params::Validate qw(:all);
use Template;
use Fatal qw(close);
use Encode;

#use Smart::Comments;

use Meter::LogParams;
use Meter::DBI;
use Meter::Utils qw(
    check_METER_ROOT
);

Readonly my $SQLITE_COMMAND       => 'sqlite3';
Readonly my $TEST_APACHE_CONF_DIR => "$ENV{'METER_ROOT'}/tests/apache";
Readonly my $TEST_APACHE_PORT     => 8080;
Readonly my $TEST_METER_CONFIG =>
    "$ENV{'METER_ROOT'}/tests/meter-www-common-case/meter.conf";
Readonly my $APACHE_RESTART_COMMAND => 'sudo /etc/init.d/apache2 restart';
Readonly my $TEST_WEBAPP_URL        => "http://localhost:$TEST_APACHE_PORT";

INIT {
    check_METER_ROOT();
}

sub init_tmp_db {
    my ( undef, $tmp_db ) = tempfile(
        'meter-XXXX',
        DIR    => "$ENV{'METER_ROOT'}/db",
        SUFFIX => '.db',
        UNLINK => $ENV{'DONT_CLEANUP'} ? 0 : 1,
    );

    my $schema = "$ENV{'METER_ROOT'}/db/schema.sqlite";

    my $output = `$SQLITE_COMMAND $tmp_db < $schema 2>&1`;

    if ( $CHILD_ERROR != 0 ) {
        confess "Cannot create tmp database: $output";
    }

    Meter::DBI->init_db($tmp_db);

    _setup_test_databaserow_module();

    return $tmp_db;
}

sub init_apache {

    # remove old apache configs and test dbs
    system "rm $TEST_APACHE_CONF_DIR/site-????.conf 2>/dev/null";
    system "rm $ENV{'METER_ROOT'}/db/meter-????.db 2>/dev/null";

    my %params = validate(
        @_,
        {   meter_db     => { default => init_tmp_db() },
            meter_config => { default => $TEST_METER_CONFIG },
            meter_root   => { default => $ENV{'METER_ROOT'} },
        }
    );

    my $site_config = _generate_site_config(
        meter_db     => $params{'meter_db'},
        meter_config => $params{'meter_config'},
        meter_root   => $params{'meter_root'},
        port         => $TEST_APACHE_PORT,
    );

    my $tmp_conf = _install_apache_site_config($site_config);
    _restart_apache();

    return;
}

sub get_test_webapp_url {
    return $TEST_WEBAPP_URL;
}

sub _restart_apache {
    my $output = `$APACHE_RESTART_COMMAND 2>&1`;

    if ($CHILD_ERROR) {
        confess "Failed to restart Apache: $output";
    }

    return;
}

sub _setup_test_databaserow_module {
    no warnings 'once';    ## no critic (ProhibitNoWarnings)

    ## no critic (ProhibitPackageVars)
    $Test::DatabaseRow::dbh     = Meter::DBI->db_Main();
    $Test::DatabaseRow::verbose = $ENV{'TEST_VERBOSE'};

    return;
}

sub _generate_site_config {
    my %params = validate(
        @_,
        {   meter_db     => 1,
            meter_config => 1,
            meter_root   => 1,
            port         => 1,
        }
    );

    my $tt = Template->new( INCLUDE_PATH => $TEST_APACHE_CONF_DIR );

    my $site_config = q{};
    $tt->process( 'site.conf.tt2', {%params}, \$site_config )
        or confess( 'Cannot build site config: ' . $tt->error() );
    ### site_config: $site_config

    return $site_config;
}

sub _install_apache_site_config : Log( params => 0 ) {
    my $site_config = shift;

    my ( $tmp_fh, $tmp_conf ) = tempfile(
        'site-XXXX',
        DIR    => $TEST_APACHE_CONF_DIR,
        SUFFIX => '.conf',
        UNLINK => $ENV{'DONT_CLEANUP'} ? 0 : 1,
    );

    ## no critic (RequireBracedFileHandleWithPrint)
    print $tmp_fh $site_config;
    close $tmp_fh;

    return $tmp_conf;
}

1;
